package com.lagou.rpc.consumer.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.util.concurrent.Callable;

/**  执行send方法时，执行这个类
 *   客户端处理类  处理消息入站 继承接口
 *   需要完成的功能：
 *   1. 发送消息
 *   2. 接收消息
 *   netty是异步机制，发送完消息并不是马上去接收消息，为了解决这个问题，采用线程的方式，等待和唤醒机制
 */
public class RpcClientHandler extends SimpleChannelInboundHandler<String> implements Callable {

    // 将环境上下文提取出来 ChannelHandlerContext
    private ChannelHandlerContext context;

    //  发送的消息
    private String requestMessage;

    // 服务端传来的消息
    private String responseMessage;

    public void setRequestMessage(String requestMessage) {
        this.requestMessage = requestMessage;
    }

    /**
     *  通道连接 就绪事件
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        context = ctx;
    }

    // 因为用了线程唤醒，所以必须加同步关键字synchronized，否则报错
    @Override
    protected synchronized void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {
        responseMessage = msg; // 服务端传来的消息
        // 唤醒等待的线程
        notify();
    }

    /**     因为用了线程等待，所以必须加同步关键字synchronized，否则报错
     *  发送消息 到 服务端
     * @return  返回值是  服务端发送过来的消息
     * @throws Exception
     */
    @Override
    public synchronized Object call() throws Exception {
        context.writeAndFlush(requestMessage);// 消息发送
        // 让线程等待
        wait();
        return responseMessage;
    }
}
